﻿using XmlStudio.GraphSharp;
using XmlStudio.ViewModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using XmlStudio.ViewModel.Node;
using XmlStudio.DataLayer;
using System.Xml;
using XmlStudio.Utilities;
using XmlStudio.Models;

namespace XmlStudio.Tests {


    /// <summary>
    ///This is a test class for XmlViewModelTest and is intended
    ///to contain all XmlViewModelTest Unit Tests
    ///</summary>
    [TestClass()]
    public class XmlViewModelTest {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext {
            get {
                return testContextInstance;
            }
            set {
                testContextInstance = value;
            }
        }

        #region Additional test simpleTypes
        // 
        //You can use the following additional simpleTypes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        /// <summary>
        ///A test for InsertAfter
        ///</summary>
        [TestMethod]
        public void InsertAfterTest() {
            string xml =
@"<node1>
    <node2>
        <node6 />
    </node2>
    <node3>
        <node7 />
    </node3>
    <node4>
        <node8 />
    </node4>
    <node5>
        <node9 />
    </node5>
</node1>";

            var node1 = TreeBuilder.BuildTree(xml);
            var node2 = node1.ChildNodes[0];
            var node3 = node1.ChildNodes[1];
            var node4 = node1.ChildNodes[2];
            var node5 = node1.ChildNodes[3];
            var node6 = node2.ChildNodes[0];
            var node7 = node3.ChildNodes[0];
            var node8 = node4.ChildNodes[0];
            var node9 = node5.ChildNodes[0];

            var app = new App();
            var model = ModelFactory.CreateXmlModel();
            MainWindow w = null; // new MainWindow(app, Interfaces.ApplicationMode.Xml);
            var controller = Controllers.ControllerFactory.CreateController(model, w);
            XmlViewModel viewModel = new XmlViewModel(app, controller, model, w);

            XmlGraph graph = new XmlGraph();

            XmlDocument doc = new XmlDocument();
            var element = doc.CreateElement("test");
            var newElement = doc.CreateElement("toInsert");
            BigXmlNode node = BigXmlNodeInternal.Create(element, new int[] { 1 }, new int[] { 1 });
            BigXmlNode nodeToInsert = BigXmlNodeInternal.Create(newElement, new int[] { 1 }, new int[] { 1 });

            XmlElementViewModel vertex01 = new XmlElementViewModel(node1, null);
            XmlElementViewModel vertex02 = new XmlElementViewModel(node2, null);
            XmlElementViewModel vertex03 = new XmlElementViewModel(node3, null);
            XmlElementViewModel vertex04 = new XmlElementViewModel(node4, null);
            XmlElementViewModel vertex05 = new XmlElementViewModel(node5, null);
            XmlElementViewModel vertex06 = new XmlElementViewModel(node6, null);
            XmlElementViewModel vertex07 = new XmlElementViewModel(node7, null);
            XmlElementViewModel vertex08 = new XmlElementViewModel(node8, null);
            XmlElementViewModel vertex09 = new XmlElementViewModel(node9, null);

            XmlNodeEdge edge01 = new XmlNodeEdge("1 -> 2", vertex01, vertex02);
            XmlNodeEdge edge02 = new XmlNodeEdge("1 -> 3", vertex01, vertex03);
            XmlNodeEdge edge03 = new XmlNodeEdge("1 -> 4", vertex01, vertex04);
            XmlNodeEdge edge04 = new XmlNodeEdge("1 -> 5", vertex01, vertex05);
            XmlNodeEdge edge05 = new XmlNodeEdge("2 -> 6", vertex02, vertex06);
            XmlNodeEdge edge06 = new XmlNodeEdge("3 -> 7", vertex03, vertex07);
            XmlNodeEdge edge07 = new XmlNodeEdge("4 -> 8", vertex04, vertex08);
            XmlNodeEdge edge08 = new XmlNodeEdge("5 -> 9", vertex05, vertex09);

            graph.AddVertex(vertex01);
            graph.AddVertex(vertex02);
            graph.AddVertex(vertex03);
            graph.AddVertex(vertex04);
            graph.AddVertex(vertex05);
            graph.AddVertex(vertex06);
            graph.AddVertex(vertex07);
            graph.AddVertex(vertex08);
            graph.AddVertex(vertex09);

            graph.AddEdge(edge01);
            graph.AddEdge(edge02);
            graph.AddEdge(edge03);
            graph.AddEdge(edge04);
            graph.AddEdge(edge05);
            graph.AddEdge(edge06);
            graph.AddEdge(edge07);
            graph.AddEdge(edge08);

            viewModel.Graph = graph;

            XmlElementViewModel vertexToInsert = new XmlElementViewModel(nodeToInsert, null);
            viewModel.InsertAfter(vertexToInsert, vertex01, Enums.InsertMode.After, vertex03);

            Assert.AreEqual<int>(10, graph.VertexCount);
            Assert.AreEqual<int>(9, graph.EdgeCount);
            var edgesOfVertex1 = graph.OutEdges(vertex01);
            Assert.AreEqual<int>(5, edgesOfVertex1.Count());
        }
    }
}
